/**
 * 
 */
package com.radeonsys.litmus.data.schema;

import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.util.Assert;

import com.radeonsys.litmus.data.converters.Converter;

/**
 * Builds instance of {@link Schema}
 * 
 * @author Ranganath Kini (ranganathkini at gmail dot com)
 * @version 1.0
 */
public class SchemaBuilder {
	
	// stores the field definitions as they are added
	private final Map<String, Converter<?, ?>> _fieldMap =
		new LinkedHashMap<String,Converter<?,?>>();
	
	/**
	 * Creates a new instance of <code>SchemaBuilder</code>
	 */
	public SchemaBuilder() {
		// DO NOTHING
	}
	
	/**
	 * Adds a field with the specified name to the schema that will be built.
	 * 
	 * @param fieldName		name of the field to be added
	 * @param converter		reference to an implementation {@link Converter} that
	 * 						will be used to convert the field values
	 * 
	 * @return	reference to this instance of {@link SchemaBuilder}
	 */
	public SchemaBuilder addField(String fieldName, Converter<?, ?> converter) {
		Assert.notNull(fieldName, "Field name must be specified");
		Assert.notNull(converter, "Field converter must be specified");
		
		if (_fieldMap.containsKey(fieldName))
			throw new IllegalStateException("A field named " + fieldName + " was already added.");
		_fieldMap.put(fieldName, converter);
		return this;
	}
	
	/**
	 * Builds and returns an implementation of {@link Schema} to the caller
	 * 
	 * @return	reference to an implementation of {@link Schema} with the 
	 * 			added fields
	 * 
	 * @throws	IllegalStateException
	 * 				if an attempt was made to build the schema without adding any fields
	 */
	public Schema build() {
		if (_fieldMap.isEmpty())
			throw new IllegalStateException("Cannot build a schema without field. Did you forget to add fiels?");
		return new DefaultSchema(_fieldMap);	
	}
	
}
